#!/usr/bin/env python
# -*- coding: utf-8 -*-
#code:utf-8
#
# Copyright(C) 2011 SupDo.com
# Licensed under the GUN License, Version 3.0 (the "License");
# 
# File:        html.py
# Author:      KuKei
# Create Date: 2012-1-29
# Description: Html处理模块
# Modify Date: 2012-1-29

import re

def truncHtml(content, maxlen=200, format='html', showimg=True, end='...'):
    """
    截取html内容
    content：需要处理的html内容
    maxlen：为显示字数
    format：为截取内容的格式 [html,text]
    showimg：为是否显示图片 [boolean]
    end：结束内容
    """
    #截取纯文本
    if format == 'text':
        content = re.sub('(<)[^<>]*(>?)', '', content)
        content = re.sub('&nbsp;', '', content)#过虑掉&nbsp;
        if len(content) <= maxlen:
            return content
        return '%s%s' % (content[:maxlen],end)
    #过虑图片标记
    if not showimg :
        content = re.sub('</?(IMG|img)[^<>]*/?>', '', content)
    
    n = 0
    i = 0
    result = ''
    temp = ''
    isCode = False  #是不是HTML代码
    isHtml = False  #是不是HTML特殊字符,如&nbsp;
    #获取指定长度的内容
    for i in range(len(content)):
        temp = content[i]
        if temp == '<':
            isCode = True
        elif temp == '&':
            isHtml = True
        elif temp == '>' and isCode:
            n = n -1
            isCode = False
        elif temp == ';' and isHtml:
            isHtml = False
        if not isCode and not isHtml:
            n = n + 1
        result += temp
        if n >= maxlen:
            break
    
    left_content = content[i+1:]
    #将本身非成对的标签删除
    rsg = re.compile(r'<(br|hr|img)\s*/?>', re.I)
    left_content = rsg.sub('', left_content)
    #将剩余部门的成对标签及标签内的text删除
    rdb = re.compile(r'<(?P<tag>\w+)[^>]*>[^<]*</(?P=tag)>', re.I)
    while rdb.search(left_content):
        left_content = rdb.sub('', left_content)
    #找出剩余部分的标签
    rlt = re.compile(r'</[^>]*>', re.I)
    left_result = ''.join(rlt.findall(left_content))
    #剩余部分的标签即需要补全的内容
    result = result + end + left_result
    return result

'''
一下两个函数是网上网友提供的方式，不太适合我的要求，不过感谢他们提供的思路
'''
#===============================================================================
# class MyHTMLParser():
#    '''
#    在处理HTML文档时，最让人头痛的莫过于HTML标签不规范的问题。一般都会选择Beautiful Soup库来处理，但当我们只需要简单的将“坏”标签补充完整时，这显得有些“大材小用”了。
# 下面的小函数就是用来完成这个任务的，此外他还会删除多余的空格、<br />、<hr />、空标签及空标签属性：
#    '''
#    def beautify(self, html):
#        nopairtag = ['br', 'img', 'hr']
#        reg = {'split': r'(</?[a-z][^>]*?>)',
#               'tag': r'<(?P<slash>/?)(?P<tag>[a-z]\w*)(?P<attr>[^>]*)>',
#               'badtag': r'^<(?:[^\0]*)|(?:[^\0]*)>$', #  just remove it
#               'emptyattr': r'(\s+[a-z]\w*\s*?=\s*?(\'|")\s*?\2)',
#               'remove': r'<link[^>]*?>|<style[^>]*?>[^\0]*?</style\s*?>|<script[^>]*?>[^\0]*?</script\s*?>|<script[^>]*?/?\s*?>|<([a-z]\w*)[^>]*>\s*?</\1\s*?>',
#               'br': r'(<br\s*?/?\s*?>\s*?){1,}'}
#        rs = re.compile(reg['split'], re.I)
#        rt = re.compile(reg['tag'], re.I)
#        rbt = re.compile(reg['badtag'], re.I)
#        rea = re.compile(reg['emptyattr'], re.I)
#        rr = re.compile(reg['remove'], re.I)
#        rb = re.compile(reg['br'], re.I)
#        
#        segment = [seg for seg in rs.split(re.sub(r'\s{2,}', ' ', re.sub(r'>\s+<', '><', html))) if seg!='']
#        html = []
#        opentag = []
#        closetag = []
#        for i in range(0, len(segment)):
#            match = rt.match(segment[i])
#            if match:
#            # HTML tag
#                html.append(rea.sub('', segment[i]))
#                tag = match.group('tag')
#                if tag not in nopairtag:
#                    if match.group('slash'):
#                    # close
#                        if tag in opentag:
#                            opentag.reverse()
#                            opentag.remove(tag)
#                            opentag.reverse()
#                        else:
#                            closetag.append(tag)
#                    else:
#                    # open
#                        opentag.append(tag)
#                else:
#                    if not rbt.match(segment[i]):
#                        html.append(segment[i])
#        # fixed tag
#        opentag.reverse()
#        for tag in opentag:
#            html.append('</%s>' % tag)
#        for tag in closetag:
#            html.insert(0, ('<%s>' % tag))
#        # remove empty tag, link tag, script tag and fixed br tag
#        return rb.sub('<br />', rr.sub('', ''.join(html)))
#    
# 
# def truncateHtml(content, args=''):
#    """
#    截取html内容
#    args 完全格式 "120 html img"
#    第一个参数为显示字数
#    第二个参数为截取内容的格式 [html,text]
#    第三个参数为是否显示图片 [img]
#    如果第三个参数为text 则第三参数不起作用
#    默认是html格式不显示图片
#    """
#    maxlen=50           #显示字数
#    format = 'html'     #html：保留html格式截取 text:纯文本取
#    showimg = ''        #空　表示不显示图片 img 显示图片
#    end='...'              #省略显示符号
#    if args:
#        bits = args.split(' ')
#        if len(bits) == 3:
#            maxlen, format, showimg = bits
#        elif len(bits) == 2:
#            maxlen, format = bits
#        else:
#            maxlen = args
#    maxlen = int(maxlen)
#    #过虑段落标记
#    content = re.sub('</?(P|p)[^<>]*/?>', '', content)
#    #截取纯文本
#    if format == 'text':
#        content = re.sub('(<)[^<>]*(>?)', '', content)
#        content = re.sub('&nbsp;', '', content)#过虑掉&nbsp;
#        if len(content) <= maxlen:
#            return content
#        return '%s%s' % (content[:maxlen],end)
#    #过虑图片标记
#    if showimg != 'img':
#        content = re.sub('</?(IMG|img)[^<>]*/?>', '', content)
#    n = 0
#    result = ''
#    temp = ''
#    isCode = False  #是不是HTML代码
#    isHtml = False  #是不是HTML特殊字符,如&nbsp;
#    #获取指定长度的内容
#    for i in range(len(content)):
#        temp = content[i]
#        if temp == '<':
#            isCode = True
#        elif temp == '&':
#            isHtml = True
#        elif temp == '>' and isCode:
#            n = n -1
#            isCode = False
#        elif temp == ';' and isHtml:
#            isHtml = False
#        if not isCode and not isHtml:
#            n = n + 1
#        result += temp
#        if n >= maxlen:
#            break
#    #取出所有html标记
#    temp_result = re.sub('(>)[^<>]*(<?)','><', result)
#    temp_result = temp_result.lower()
#    
#    if len(content) - len(temp_result) < maxlen:
#        return content
#    result += str(end)
#    #去掉不需要结束标记html标记
#    rg = "</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>"
#    temp_result = re.sub(rg, '',temp_result)
#    #去掉成对的html标记
#    temp_result = re.sub('<([a-zA-Z]+)[^<>]*>(.*?)</\\1>', '',temp_result)
#    #取出html标记符号
#    arr = re.findall('<([a-zA-Z]+)[^<>]*>', temp_result)
#    #补全html标记
#    for i in range(len(arr)):
#        result += '</%s>' % arr[len(arr)-i-1]
#    return result
#===============================================================================
